/*
 * @Author: song
 * @Description:提高静态辅助函数
 * @Date: 2024年04月17日 星期三 10:04:42
 * @Modify:
 */

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Networking;

namespace SCore.Util
{
    public class UnityUtils
    {
        #region UIUtils

        private static List<RaycastResult> _uiRaycastResultCache = new List<RaycastResult>();

        public static GameObject GetFirstSelectUIGameObject(Vector2 position, out bool overGui)
        {
            var uiEventSystem = EventSystem.current;
            if (uiEventSystem != null)
            {
                var uiPointerEventData = new PointerEventData(uiEventSystem);
                uiPointerEventData.position = position;

                uiEventSystem.RaycastAll(uiPointerEventData, _uiRaycastResultCache);
                if (_uiRaycastResultCache.Count > 0)
                {
                    overGui = true;
                    return _uiRaycastResultCache[0].gameObject;
                }
                else
                {
                    overGui = false;
                    return null;
                }
            }
            else
            {
                overGui = false;
                return null;
            }
        }

        #endregion

        #region PathUtils

        private static readonly string[,] BuildinPaths = new string[,]
        {
            { "{CurrentDir}", GetCurrentDirectory() },
            { "{PersistentDir}", GetPersistentDirectory() },
            { "{StreamingAssetsDir}", GetStreamingAssetsDirectory() },
        };

        public static string GetCurrentDirectory()
        {
            string s = Directory.GetCurrentDirectory();
#if UNITY_EDITOR || UNITY_STANDALONE
            return s.Replace('\\', '/'); //因为要处理windows平台所以让所有的standalone都进行处理
#else
            return s;
#endif
        }

        public static string GetPersistentDirectory()
        {
            string s = Application.persistentDataPath;
#if UNITY_EDITOR || UNITY_STANDALONE
            return s.Replace('\\', '/'); //因为要处理windows平台所以让所有的standalone都进行处理
#else
            return s;
#endif
        }

        public static string GetCacheDirectory()
        {
#if UNITY_EDITOR || UNITY_STANDALONE
            string s = Directory.GetCurrentDirectory();
            s.Replace('\\', '/');
            return s + "/Data";
#else
            return Application.persistentDataPath;
#endif
        }

        public static string GetStreamingAssetsDirectory()
        {
            string s = Application.streamingAssetsPath;
#if UNITY_EDITOR || UNITY_STANDALONE
            return s.Replace('\\', '/'); //因为要处理windows平台所以让所有的standalone都进行处理
#else
            return s;
#endif
        }

        #endregion

        #region FileUtils

        public static byte[] ReadStreamingAssets(string relativePath)
        {
            string url = GetStreamingAssetsDirectory() + "/" + relativePath;
            $"StreamingAssetsLoader ReadStreamingAssets File:{url}".Log();
            if (IsAndroid)
            {
                using (var www = UnityWebRequest.Get(url))
                {
                    var request = www.SendWebRequest();
                    while (!request.isDone)
                    {
                    }

                    var data = request.webRequest.downloadHandler.data;
                    if (data.Length == 0)
                        return null;
                    return data;
                }
            }

            string path = GetStreamingAssetsDirectory() + "/" + relativePath;
            if (File.Exists(path))
            {
                byte[] data = File.ReadAllBytes(path);
                return data;
            }

            return null;
        }

        public static string ReadStreamingAssetsText(string relativePath)
        {
            string url = GetStreamingAssetsDirectory() + "/" + relativePath;
            if (IsAndroid)
            {
                using (var www = UnityWebRequest.Get(url))
                {
                    www.disposeDownloadHandlerOnDispose = true;
                    var request = www.SendWebRequest();
                    while (!request.isDone)
                    {
                    }

                    if (www.isHttpError || www.isNetworkError)
                        return null;
                    return request.webRequest.downloadHandler.text;
                }
            }

            string path = GetStreamingAssetsDirectory() + "/" + relativePath;
            if (File.Exists(path))
            {
                string text = File.ReadAllText(path);
                return text;
            }

            return null;
        }

        #endregion

        #region Platform

        public static bool IsAndroid
        {
            get
            {
#if UNITY_ANDROID && !UNITY_EDITOR
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsEditorAndroid
        {
            get
            {
#if UNITY_ANDROID && UNITY_EDITOR
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsAndroidModel
        {
            get
            {
#if UNITY_ANDROID
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsIOS
        {
            get
            {
#if UNITY_IOS && !UNITY_EDITOR
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsEditorIOS
        {
            get
            {
#if UNITY_IOS && UNITY_EDITOR
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsIOSModel
        {
            get
            {
#if UNITY_IOS
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsEditor
        {
            get
            {
#if UNITY_EDITOR
                return true;
#else
                return false;
#endif
            }
        }

        public static bool IsStandalone
        {
            get
            {
#if UNITY_STANDALONE
                return true;
#else
                return false;
#endif
            }
        }

        public static string GetBuildTargetName()
        {
#if UNITY_ANDROID
            return "Android";
#elif UNITY_IOS
            return "iOS";
#elif UNITY_STANDALONE_OSX
            return "StandaloneOSX";
#elif UNITY_STANDALONE_WIN
            return "StandaloneWindows64";
#else
            return "Android";
#endif
        }

        public static string WWWProtoHead
        {
            get
            {
#if UNITY_ANDROID && !UNITY_EDITOR
                return "";
#else
                return "file://";
#endif
            }
        }

        #endregion

        #region IO

        public static void CopyDirectory(string sourceDirectory, string targetDirectory,
            System.Func<string, bool> func = null)
        {
            DirectoryInfo sourceDir = new DirectoryInfo(sourceDirectory);
            if (!sourceDir.Exists)
            {
                return;
            }

            DirectoryInfo targetDir = new DirectoryInfo(targetDirectory);
            if (!targetDir.Exists)
            {
                targetDir.Create();
            }

            var files = sourceDir.GetFiles("*", SearchOption.TopDirectoryOnly);
            foreach (var file in files)
            {
                if (func == null || func(file.FullName))
                {
                    var targetFileName = Path.Combine(targetDir.FullName, file.Name);
                    file.CopyTo(targetFileName, true);
                    File.SetAttributes(targetFileName, FileAttributes.Normal);
                }
            }

            var dirs = sourceDir.GetDirectories("*", SearchOption.TopDirectoryOnly);
            foreach (var subdir in dirs)
            {
                string targetDirName = Path.Combine(targetDir.FullName, subdir.Name);
                CopyDirectory(subdir.FullName, targetDirName, func);
            }
        }

        #endregion

        #region UnityWeb

        public static UnityWebRequest GetUnityWebRequestNoSafe(string url)
        {
            var request = UnityWebRequest.Get(url);
            BypassCertificate.Bypass(request);
            // 禁用 SSL 证书验证
            // request.certificateHandler = new BypassCertificate();
            return request;
        }

        #endregion
    }
}